아이템26
타입 추론에 문맥이 어떻게 사용되는지 고려하기
- 타입스크립트는 추론시 단순한 값만 고려하지 않고 존재하는 곳의 문맥까지 고려한다.
// string 추론
let nameLet = "kim";
type Name = typeof nameLet;
// const 추론
const nameConst = "kim";
type NameC = typeof nameConst;
튜플 사용시의 문제점
- 문자열 리터럴 타입과 마찬가지로 튜플 타입에서도 문제가 발생한다.
declare function panTo(where: [number, number]): void;
const tuple = [1, 2];
// (4) Error: 'number[]' 형식의 인수는 '[number, number]' 형식의 매개 변수에 할당될 수 없습니다.
panTo(tuple);
- 위 코드는
[number,number]가 아닌number[]로 추론되어 문제가 발생한다. - 이를 해결하기 위해
as const를 사용하면 내부까지 상수임을 타입스크립트에게 알려준다.
function panTo(where: [number, number]): void;
const tuple = [1, 2, 3] as const;
// 'readonly [1, 2, 3]' 형식의 인수는 'readonly [number, number]' 형식의 매개 변수에 할당될 수 없습니다.
panTo(tuple);
- 다만 이런 방법은 너무 과하게 정확해
panTo타입의 시그니처를where내용이 불변임을 보장하지 못한다. 이를 해결하기위해readonly를 붙여서 문제를 해결해야한다.
function panTo(readonly : where :[number, number]): void;
객체 사용시 주의점
- 객체의 경우에도 튜플처럼 주솟값을 갖는 참조에 대한 변경 불가능이라는 의미를 갖기 때문에 내부의 property는 일반적으로 let으로 선언한 변수처럼 타입 부여
((6))합니다.
const champion = {
name: "Aatrox",
speed: 345,
};
/**
* (6)
* {
* name: string;
* speed: number;
* }
*/
const champion = {
name: "Aatrox" as const,
speed: 345,
};
/**
* {
* name: "Aatrox";
* speed: number;
* }
*/
const champion = {
name: "Aatrox",
speed: 345,
} as const;
/**
* {
* readonly name: "Aatrox";
* readonly speed: 345;
* }
*/
콜백을 상수로 뽑아내면 문장이 소실되고 오류가 발생한다.
- 이를 해결하기 위해
const사용시에는 매개변수에 타입을 줘야한다.
Item 26 결론
- 별도의 변수로 뽑아서 사용한다면 타입 선언을 추가하는 방법 고려하기
- 정말 상수라면 타입 단언(as const)을 사용하고, 타입 단언에서 문제가 있다면 사용한 곳에서 발생하는 것을 인지하기